var MemberSelector = function($wrapper, cfg){
    var _this = this;    
    this.$wrapper = $($wrapper).addClass('adderFormField');    
    this.config = $.extend({}, cfg);    
    this.$wrapper.data('formField', this);
    Observable.enable(this);    
    this.$wrapper.append([
        '<div class="formValuesContainer membersPanel"></div>',                        
        '<a class="addBtn showMember">+</a>'
    ].join(''));    
    //尺寸大小.
    if(this.config['size']){
        this.$wrapper.css({
            width : this.config['size']['width'],
            height : this.config['size']['height']
        });
    } else {
        this.$wrapper.css({
            width : this.config['width'],
            height : this.config['height']
        });
    }
    //选择 member控件.
    this.memberList = this.$wrapper.find('.membersPanel').stringList({
        theme : 'membersList',
        deletable : true,
        selectable : _this.config['clickable'],
        addable : false,
        isDeletingConfirm : _this.config['isDeletingConfirm'] || false,
        stringItemTmp : '<img src="<%=item.icon%>" width="30px"/><%=item.text%>',
        onClick : function(val, isSelected, $stringItem){
            if(_this.config['clickable'] != false){
                if(_this.isSingleUser()){
                    $stringItem.removeClass('selected');
                    return;
                }
                if($stringItem.attr('type') == 'group'){
                    $stringItem.removeClass('selected');
                    bubble.msg(lan('app.im.participant.setAdminTip'));
                }
            }
        }
    }).data('stringList');
     
    //选择 member控件状态连动效果.
    this.memberList.on('add', function(){});
    this.memberList.on('remove', function(id){
        _this.fire('remove', id);
        _this.fire('change', id);
    });

    _this.setRoot(this.config['root']);

    //events
    if(this.config['events']){
        Object.each(this.config['events'], function(eventName, handler){
            _this.on(eventName, handler);
        });
    }

    if(this.config['mode'] == 'expand'){
        this.$wrapper.find('.showMember').trigger('click');
        this.readonly();
        this.memberList.editable();
    }

    if(this.config['noAdd'] === true){
        this.$wrapper.find('.addBtn').hide();
    }

    if(this.config['width100'] === true){
        this.$wrapper.find('.formValuesContainer').css({
            borderRight : 'solid 1px #F0EAEA',
            width : 'calc(100% - 13px)',            
            borderRadius: 3
        });
    }
};

MemberSelector.prototype.getAdmins = function(){
    return this.memberList.getValues();
};

MemberSelector.prototype.clearAdmins = function(){
    return this.memberList.clearCheckState();
};

MemberSelector.prototype.setAdmins = function(members){
    if(members){
        var state = {};
        for(var i=0; i<members.length; i++){
            state[members[i]['id']] = true;            
        } 
        this.memberList.setCheckState(state);
    } 
    return this;
};


MemberSelector.prototype.addCurrentUser = function(){
    var user = ujs.util.session.getCurrentUserInfo();
    this.addMember( user['id'], user['name'], user['icon'], 'user', false );
    return this;
};

MemberSelector.prototype.addMember = function(id, name, icon, type, deletable){
    if(!this.memberList.getOptionByValue(id).length){    
        this.memberList.addItem({
            deletable : deletable,
            text : name,
            value : id,
            icon : icon ? icon : (type === 'user' ? ujs.getConfigRes('defUserIcon') : ujs.getConfigRes('defGroupIcon'))
        }, function($newItem){
            $newItem.attr('type', type);
        });        
    }
    this.fire('change');
    return this;
};

MemberSelector.prototype.setRoot = function(root){
    var _this = this;
    this.$wrapper.find('.treeNodeSelectorWrapper').remove();    
    //选择 member下拉tree控件.
    this.memberSelector = this.$wrapper.find('.showMember').treeNodeSelector({
        closable : true,
        mode : this.config['mode'] == 'expand' ? 'isSelectHidden' : '',
        pos : this.config['treePos'] || 'bottom', 
        search : this.config['search'],        
        noUser : _this.config['noUser'],
        noGroup : _this.config['noGroup'],
        initially_open : _this.config['initially_open'],
        style : _this.config['memberStyle'] || 'height:220px;',
        root : root || {
            url : '/apis/usergroup/type/{0}'.format(_this.config['treeType'])
        }, 
        useGuid : this.config['useGuid'],       
        exclusion : _this.config['exclusion'] || [],        
        treeConfig : {
            plugins : ["themes", "json_data", "ui" , "types"],
            types : {
                types : {
                    group : {
                        icon : { image : ujs.getRes('images/common16/user_group.png') }                           
                    },
                    user : {
                        icon : { image : ujs.getRes('images/common16/user_male.png') }
                    },
                    cr : {
                        icon : { image : ujs.getRes('images/common16/hands.png') }
                    }
                }
            },
            json_data : {
                ajax : {
                    url : function($node) {                                   
                        return '/apis/usergroup/{0}/subs?id={0}&cr={1}'.format($node.attr('id'), $node.attr('cr') || '');
                    }
                }
            }
        },        
        nodeDataAdapter : MemberSelector.da(),
        searchBoxConfig : function(rootNodes){
            var rootGroupIDs = [];
            for(var i=0; i<rootNodes.length; i++){
                rootGroupIDs.push(rootNodes[i].attr['id']);
            }
            rootGroupIDs = rootGroupIDs.join(',');
            return {
                api : function(){
                    return '/apis/usergroup/subusers/search?q={text}&o=&l=&ugs=' + rootGroupIDs;
                }, 
                placeholder : lan('app.im.participant.searchUser'),
                listHeight : 195,
                itemTmp : [
                    '<div tt="<%=o.id%>" uid="<%= o.id %>" icon="<%=o.icon%>">',
                        '<div style="float:left;">',
                            '<img src="<%= o.icon || ujs.getRes("images/im/user/user-256.png") %>" width="40px" height="40px" />',
                        '</div>',
                        '<div class="name" style="float:right;width:calc(100% - 45px);"><%= o.name %></div>',
                        '<div style="float:right;width:calc(100% - 45px);">From:<%= $.map(o.groups, function(group){return group["name"]}).join(", ") %></div>',
                    '</div>'
                ].join('')
            };
        }
    }).data('treeNodeSelector');
    
    this.memberSelector.on('selectNode', function(id, text, icon, node, $node){
        if(node){
            var type = node.attr.rel;
        } else {
            var type = 'user';
            icon = icon || ujs.getConfigRes('defUserIcon');
        }
        if(_this.config['noSelectGroup'] === true && type != 'user'){
            return false;
        }
        if($node){
            text = $node.find('.name').text();
        }
        if(_this.fire('add', id, text, icon, type, node) !== false){
            _this.fire('addMember', id, text, icon, type);
            _this.addMember(id, text, icon, type);
        }
        return false;
    });
    this.memberSelector.on('rootLoaded', function(roots){
        _this.fire('rootLoaded', roots);
    });
};

MemberSelector.prototype.addMembers = function(members){
    if(members){
        for(var i=0; i<members.length; i++){
            this.addMember( 
                members[i][ this.config['useGuid'] ? 'guid' : 'id' ], 
                members[i]['name'],
                members[i]['icon'],  
                members[i]['type'] !== 10 ? 'group' : 'user'
            );
        } 
    } 
    return this;
};

MemberSelector.da = function(id){
    return function(){
        this.fun = function(nodes){            
            var newNodes = [];
            for(var i=0; i<nodes.length; i++){
                var data = { 
                    'attr' : { 
                        'id' : nodes[i][id || 'id'],
                        'rel' : nodes[i]['cr'] ? 'cr' : (nodes[i]['rel'] || 'group'),
                        'guid' : nodes[i]['guid'],
                        'cr' : nodes[i]['cr'] || '',
                        'icon' : nodes[i]['icon']
                    },                     
                    'data' : nodes[i]['name'],
                    'state' : nodes[i]['state'] || ( nodes[i]['rel'] == 'user' ? 'closed' : 'closed')
                };
                if(nodes[i]['rel'] == 'user'){                    
                    data['attr']['class'] = 'jstree-leaf';
                    data['leaf'] = true;
                    data['isLeaf'] = true;
                    data['isleaf'] = true;
                    data['children'] = false;
                }
                newNodes.push(data);
            } 
            return newNodes;
        };
    }.extend(DataAdapter);
}; 

MemberSelector.prototype.getMembers = function(){
    return $.map(this.memberList.getOptions(), function(item){
        return item.value;
    });        
};

MemberSelector.prototype.refreshRoot = function(){
    this.memberSelector.refreshNode();
};

/**
 * 获取选中的  users 和 groups.
 */
MemberSelector.prototype.getUserAndGroup = function(){
    var _this = this,       
        groups = _this.memberList.getOptions(function($strItem){
            return $strItem.attr('type') === 'group';
        }),       
        users = _this.memberList.getOptions(function($strItem){
            return $strItem.attr('type') === 'user';
        }); 
               
    return {
        groups : $.map(groups,function(item){
            return item.value;
        }), 
        users : $.map(users,function(item){
            return item.value;
        })
    };   
};

MemberSelector.prototype.isSingleUser = function(){
    var members = this.getUserAndGroup();
    return !members['groups'].length && members['users'].length < 2;
};

MemberSelector.prototype.reset = function(){
    this.memberList.clearItems();
    return this;
};

MemberSelector.prototype.readonly = function(){
    this.$wrapper.find('.membersPanel').css({
        'width' : 'calc(100% - 12px)',
        'border-right' : 'solid 1px #f0eaea',
        'border-radius' : '3px'
    });
    this.$wrapper.find('.addBtn').hide();
    this.memberList.readonly();
};

MemberSelector.prototype.editable = function(){
    this.$wrapper.find('.membersPanel').css({
        'width' : 'calc(100% - 70px)',
        'border-right' : 'none',
        'border-radius' : '3px 0px 0px 3px'
    });
    this.$wrapper.find('.addBtn').show();
    this.memberList.editable();
};